package com.hulk.dryad.activiti7.config;


import com.hulk.dryad.manage.framework.mdc.wrapper.ThreadPoolTaskExecutorMdcWrapper;
import lombok.extern.slf4j.Slf4j;
import org.activiti.spring.boot.ProcessEngineAutoConfiguration;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Author: hulk
 * @E-mail: 29572320@qq.com
 * @Date: Create in 2018/9/20 下午2:43
 */

@Configuration(proxyBeanMethods = false)
@AutoConfigureBefore(ProcessEngineAutoConfiguration.class)
public class ActivitiAsyncExecutorConfig {

	private static final int PROCESSORS = Runtime.getRuntime().availableProcessors();
	/**
	 * Set the ThreadPoolExecutor's core pool size.
	 */
	private static final int COREPOOL_SIZE = PROCESSORS;
	/**
	 * Set the ThreadPoolExecutor's maximum pool size.
	 */
	private static final int MAXPOOL_SIZE = PROCESSORS * 2;
	/**
	 * Set the capacity for the ThreadPoolExecutor's BlockingQueue.
	 */
	private static final int QUEUE_CAPACITY = PROCESSORS * 3;

	@Bean("applicationTaskExecutor")
	public TaskExecutor applicationTaskExecutor() {
		//TODO 未解决 线程池 MDC 传递问题
		ThreadPoolTaskExecutorMdcWrapper executor = new ThreadPoolTaskExecutorMdcWrapper();
		executor.setCorePoolSize(COREPOOL_SIZE);
		executor.setMaxPoolSize(MAXPOOL_SIZE);
		executor.setQueueCapacity(QUEUE_CAPACITY);
		executor.setThreadNamePrefix("applicationTaskExecutor-");

		// rejection-policy：当pool已经达到max size的时候，如何处理新任务
		// CALLER_RUNS：不在新线程中执行任务，而是由调用者所在的线程来执行
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		executor.initialize();
		return executor;
	}



}
